package com.simons.common.spring.config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.logging.log4j.core.config.Order;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import com.simons.common.exception.CommonException;
import com.simons.common.service.AbstractInitService;
import com.simons.common.service.InitService;
import com.simons.common.spring.service.SpringContextHolder;

import lombok.extern.log4j.Log4j2;

@Log4j2
@Component
@Order(value = 0)
public class EndStartedListener implements ApplicationListener<ContextRefreshedEvent>{

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {

		if(((ApplicationContextEvent) event).getApplicationContext().getParent() == null){
			try {
				this.initSystem(SpringContextHolder.getApplicationContext());
			} catch (CommonException e) {
				log.error("", e);
			}
		}
		
	}

	public void initSystem() throws CommonException{
		this.initSystem(SpringContextHolder.getApplicationContext());
	}
	
	public void initSystem(ApplicationContext context) throws CommonException{
		String beans[] = context.getBeanDefinitionNames();
		
		log.info("bean length:"+beans.length);
		Map<Integer, List<Object>> beanMap = new HashMap<Integer, List<Object>>();
		for(String bean : beans){
			Object obj = context.getBean(bean);
			
			if(obj instanceof InitService){
				InitService initService = (InitService)obj;
				
				Integer key = initService.getOrder();
				List<Object> beanList = beanMap.get(key);
				if(beanList == null){
					beanList = new ArrayList<Object>();
					beanMap.put(key, beanList);
				}
				beanList.add(initService);
			} else if(obj instanceof AbstractInitService){
				AbstractInitService initService = (AbstractInitService)obj;
				Integer key = initService.getOrder();
				
				List<Object> beanList = beanMap.get(key);
				if(beanList == null){
					beanList = new ArrayList<Object>();
					beanMap.put(key, beanList);
				}
				beanList.add(initService);
			}
		}
		if(beanMap.isEmpty()){
			return;
		}
		Set<Integer> keySet = beanMap.keySet();
		Integer[] keyArr = keySet.toArray(new Integer[] {});   
		Arrays.sort(keyArr);
		for(int i = keyArr.length - 1; i >= 0; i --){
			Integer IKey = keyArr[i];
			List<Object> beanList = beanMap.get(IKey);
			for(Object obj : beanList){
				if(obj instanceof InitService){
					InitService initService = (InitService)obj;
					initService.init();
				} else if(obj instanceof AbstractInitService){
					AbstractInitService initService = (AbstractInitService)obj;
					initService.init();
				}
			}
		}
		
	}
	
}
